package com.hc.programming.array;

import com.hc.programming.util.ArrayUtil;

/**
 * 59.给你一个正整数 n ，生成一个包含 1 到 n2 所有元素，且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
 * <p>
 * 示例 1：
 * 输入：n = 3
 * 输出：[[1,2,3],[8,9,4],[7,6,5]]
 * 示例 2：
 * 输入：n = 1
 * 输出：[[1]]
 * <p>
 * 提示：
 * 1 <= n <= 20
 *
 * @author huangchao E-mail:fengquan8866@163.com
 * @version 创建时间：2024/7/8 12:08
 */
public class 螺旋矩阵II {
    public static void main(String[] args) {
        ArrayUtil.println(generateMatrix(3));
        ArrayUtil.println(generateMatrix(1));
    }

    public static int[][] generateMatrix(int n) {
//        return 方案1(n);
        return 循环不变量(n);
    }

    private static int[][] 循环不变量(int n) {
        int[][] res = new int[n][n];
        int circle = 0; // 第几圈，从0开始
        int temp = 1;
        for (int i = n / 2; i > 0; i--) { // 总圈数
            for (int j = circle; j < n - circle - 1; j++) res[circle][j] = temp++;
            for (int j = circle; j < n - circle - 1; j++) res[j][n - circle - 1] = temp++;
            for (int j = n - circle - 1; j > circle; j--) res[n - circle - 1][j] = temp++;
            for (int j = n - circle - 1; j > circle; j--) res[j][circle] = temp++;
            circle++;
        }
        if (n % 2 == 1) res[n / 2][n / 2] = temp;
        return res;
    }

    private static int[][] 方案1(int n) {
        int[][] result = new int[n][n];
        if (n == 0) {
            return result;
        }
        int rowMin = 0, rowMax = n - 1, colMin = 0, colMax = n - 1;
        int idxRow = 0, idxCol = 0;
        int i = 0;
        while (colMin <= colMax) {
            // 右移
            for (idxCol = rowMin; idxCol <= colMax; idxCol++) {
                result[idxRow][idxCol] = ++i;
            }
            rowMin++;
            if (rowMin > rowMax) break;
            idxCol--;
            // 下移
            for (idxRow = rowMin; idxRow <= rowMax; idxRow++) {
                result[idxRow][idxCol] = ++i;
            }
            colMax--;
            if (colMin > colMax) break;
            idxRow--;
            // 左移
            for (idxCol = colMax; idxCol >= colMin; idxCol--) {
                result[idxRow][idxCol] = ++i;
            }
            rowMax--;
            if (rowMin > rowMax) break;
            idxCol++;
            // 上移
            for (idxRow = rowMax; idxRow >= rowMin; idxRow--) {
                result[idxRow][idxCol] = ++i;
            }
            colMin++;
            idxRow++;
        }
        return result;
    }

}
